/*
Author: net code
Source: https://gitee.com/hxchuan000/clpc-1
Mail: surpass-hc@qq.com
*/
#include <base64.h>
#if BASE64_ENABLE_FLAG
uint32_t base64Enc(const uint8_t *inData, uint32_t inlen, uint8_t *outData, uint32_t outlen)
{
    uint8_t Tmp[4] = {0};
    uint32_t i, j = 0, Mod = inlen % 3;
    static const uint8_t DEV_C51_CODE_FLAG EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    j = (inlen + 2) / 3 * 4;
    if (!(inData && outData && j <= outlen))
    {
        return 0;
    }
    j = 0;
    for (i = 0; i < (inlen / 3); i++)
    {
        Tmp[1] = *inData++;
        Tmp[2] = *inData++;
        Tmp[3] = *inData++;
        outData[j++] = EncodeTable[Tmp[1] >> 2];
        outData[j++] = EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F];
        outData[j++] = EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F];
        outData[j++] = EncodeTable[Tmp[3] & 0x3F];
    }
    // 对剩余数据进行编码
    if (Mod == 1)
    {
        Tmp[1] = *inData++;
        outData[j++] = EncodeTable[(Tmp[1] & 0xFC) >> 2];
        outData[j++] = EncodeTable[((Tmp[1] & 0x03) << 4)];
        outData[j++] = '=';
        outData[j++] = '=';
    }
    else if (Mod == 2)
    {
        Tmp[1] = *inData++;
        Tmp[2] = *inData++;
        outData[j++] = EncodeTable[(Tmp[1] & 0xFC) >> 2];
        outData[j++] = EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)];
        outData[j++] = EncodeTable[((Tmp[2] & 0x0F) << 2)];
        outData[j++] = '=';
    }
    return j;
}
uint32_t base64Dec(const uint8_t *inData, uint32_t inlen, uint8_t *outData, uint32_t outlen)
{
    uint32_t i = 0, j = 0;
    uint32_t nValue;
    static const uint8_t DEV_C51_CODE_FLAG DecodeTable[] = {
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0X3E, 0XFF, 0XFF, 0XFF, 0X3F,
        0X34, 0X35, 0X36, 0X37, 0X38, 0X39, 0X3A, 0X3B,
        0X3C, 0X3D, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0X00, 0X01, 0X02, 0X03, 0X04, 0X05, 0X06,
        0X07, 0X08, 0X09, 0X0A, 0X0B, 0X0C, 0X0D, 0X0E,
        0X0F, 0X10, 0X11, 0X12, 0X13, 0X14, 0X15, 0X16,
        0X17, 0X18, 0X19, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0X1A, 0X1B, 0X1C, 0X1D, 0X1E, 0X1F, 0X20,
        0X21, 0X22, 0X23, 0X24, 0X25, 0X26, 0X27, 0X28,
        0X29, 0X2A, 0X2B, 0X2C, 0X2D, 0X2E, 0X2F, 0X30,
        0X31, 0X32, 0X33, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
        0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF};
    j = inlen / 4 * 3;
    if (!(inData && outData && j <= outlen))
    {
        return 0;
    }
    // 返回值
    inlen = inlen / 4 * 4;
    j = 0;
    while (i < inlen)
    {
        if (*inData != '\r' && *inData != '\n')
        {
            nValue = DecodeTable[*inData++] << 18;
            nValue += DecodeTable[*inData++] << 12;
            outData[j++] = (nValue & 0x00FF0000) >> 16;
            if (*inData != '=')
            {
                nValue += DecodeTable[*inData++] << 6;
                outData[j++] = (nValue & 0x0000FF00) >> 8;
                if (*inData != '=')
                {
                    nValue += DecodeTable[*inData++];
                    outData[j++] = nValue & 0x000000FF;
                }
            }
            i += 4;
        }
        else // 回车换行,跳过
        {
            inData++;
            i++;
        }
    }
    return j;
}
#endif
